package practica3;

import weka.classifiers.Classifier;
import weka.classifiers.Evaluation;
import weka.classifiers.rules.OneR;
import weka.core.Instances;

/**Clase que entrena el clasificador OneR mediante la evaluacion no-honesta*/
public class UpperBoundsOneR {
	
	private Evaluation bestEvaluator;
	
	public UpperBoundsOneR(){
		this.bestEvaluator = null;
	}
		
	/**
	 * Metodo que entrena el OneR y lo evalua segun la evaluacion no-honesta
	 * @param data Instancias para entrenar el clasificador OneR.
	 * @return El valor de B mas apropiado para entrenar el modelo.
	 * @throws Exception
	 */
	public void classify(Instances data) throws Exception{ 	
		double fmeasure = -1,fmeasureMax =-1;
		int bestB = -1;
		
		for(int b = 1; b<data.numInstances(); b++){ 
			
			OneR estimador = new OneR();
			estimador.setMinBucketSize(b); 	
			Evaluation evaluator = new Evaluation(data);
			evaluator = this.simpleClassify(estimador, data, data);//
			
			fmeasure = evaluator.weightedFMeasure();

			if(fmeasure>fmeasureMax){
				fmeasureMax = fmeasure;
				bestB = b;
				this.bestEvaluator = evaluator;
			}
		}	
		this.print(bestB);
	}
	
	/**
	 * Metodo que imprime los resultados del barrido de parametros realizado por el clasificador.
	 * @throws Exception
	 */
	private void print(int bestB) throws Exception{
		System.out.println("\nCALIDAD MAXIMA (NO-HONESTO)");
		System.out.println("-----------------------------");
		System.out.println("Mejor valor de B (numero de instancias minimo) en cada particion = " + bestB+"\n");
		System.out.println(this.bestEvaluator.toClassDetailsString());
		System.out.println(this.bestEvaluator.toSummaryString());
		System.out.println(this.bestEvaluator.toMatrixString());
	}
	
	/**
	 * Metodo para acceder al mejor evaluador
	 * @return devuelve el mejor evaluador
	 */
	public Evaluation getEvaluador(){
		return this.bestEvaluator;
	}
	
	/**
	 * Metodo que saca el evaluador no-honesto
	 * @param model
	 * @param trainingSet instancias para entrenar
	 * @param testingSet instancias para testear
	 * @return el evaluador
	 */
	public Evaluation simpleClassify(Classifier model, Instances trainingSet, Instances testingSet) throws Exception {
		Evaluation validation = new Evaluation(trainingSet);
		model.buildClassifier(trainingSet);
		validation.evaluateModel(model, testingSet); 

	    return validation;
	  }

}
